---
asIndexPage: true
---

import AstroIcon from '@icons/astro.svg?svgr'
import GearIcon from '@icons/gear.svg?svgr'
import GraphQLIcon from '@icons/graphql.svg?svgr'
import HalfIcon from '@icons/half.svg?svgr'
import JSIcon from '@icons/javascript.svg?svgr'
import PrettierIcon from '@icons/prettier.svg?svgr'
import StackIcon from '@icons/stack.svg?svgr'
import SvelteIcon from '@icons/svelte.svg?svgr'
import VueIcon from '@icons/vue.svg?svgr'
import { Cards, Steps, Tabs } from '@theguild/components'
import { createIndexPage, getPageMap, MDXRemote } from '@theguild/components/server'
import { GraphqlConfigInfo } from '../../../app/graphql-config-info.mdx'

# Usage

## Quickstart

<Steps>

### Installation

Install the plugin package with your favourite package manager.

```sh npm2yarn
npm i -D @graphql-eslint/eslint-plugin
```

> [!WARNING]
>
> Make sure you have [`graphql`](https://npmjs.com/package/graphql) dependency in your project.

### Configuration

Create a new
[configuration object](https://eslint.org/docs/latest/use/configure/configuration-files#configuration-objects)
in your `eslint.config.js` file to apply this plugin to `.graphql` files and configure
[the rules](/rules) you want to enforce.

```js filename="eslint.config.js"
import graphqlPlugin from '@graphql-eslint/eslint-plugin'

export default [
  // ... other config
  {
    files: ['**/*.graphql'],
    languageOptions: {
      parser: graphqlPlugin.parser
    },
    plugins: {
      '@graphql-eslint': graphqlPlugin
    },
    rules: {
      '@graphql-eslint/known-type-names': 'error'
      // ... other GraphQL-ESLint rules
    }
  }
]
```

### Lint GraphQL Definitions in Code Files <sup>_(Optional)_</sup>[#lint-in-code-files]

If you're defining GraphQL schemas or operations directly within code files (e.g., `.js`, `.jsx`,
`.ts`, `.tsx` files), check out [the usage with `.js`/`.jsx`](./usage/js) files.

### Providing GraphQL Schema <sup>_(Optional)_</sup>[#providing-schema]

Some linting rules require access to the entire GraphQL schema. For example, the
[no-unreachable-types](../rules/no-unreachable-types) rule checks that all types are reachable
through root-level fields.

To enable these rules, you need to inform ESLint how to identify and load your complete schema.

The GraphQL ESLint plugin integrates seamlessly with
[GraphQL Config](https://the-guild.dev/graphql/config), which it uses to automatically load your
schema.

> [!TIP]
>
> GraphQL Config uses [`GraphQL Tools`](https://the-guild.dev/graphql/tools) and its loaders under
> the hood to handle the schema loading. It also
> [supports multiple ways to specify your schema](https://the-guild.dev/graphql/config/docs/user/schema),
> including:
>
> - `.json` (introspection result)
> - `.graphql` files
> - a URL endpoint
> - or a raw string.

<GraphqlConfigInfo name="schema" />

Example of providing GraphQL schema:

<Tabs items={['GraphQL Config', 'Programmatic Usage']}>
<Tabs.Tab>

```js filename="graphql.config.js"
export default {
  // a path to a local `.graphql` file
  schema: './schema.graphql',

  // a glob expression to load multiple files
  schema: './src/**/*.graphql',

  // paths to multiple `.graphql` files
  schema: ['./src/schema-a.graphql', './src/schema-b.graphql', './src/schema-c.graphql'],

  // a path to a local `.json` (introspection result) file
  schema: './schema.json',

  // a URL endpoint
  schema: 'https://my-server/graphql'
}
```

</Tabs.Tab>

<Tabs.Tab>

```diff filename="eslint.config.js"
import graphqlPlugin from '@graphql-eslint/eslint-plugin'

export default [
  // ... other config
  {
    files: ['**/*.graphql'],
    languageOptions: {
      parser: graphqlPlugin.parser,
+     parserOptions: {
+       graphQLConfig: {
+         schema: './schema.graphql'
+       }
+     }
    },
    plugins: {
      '@graphql-eslint': graphqlPlugin
    },
    rules: {
      '@graphql-eslint/no-unreachable-types': 'error'
    }
  }
]
```

</Tabs.Tab>
</Tabs>

### Providing GraphQL Operations <sup>_(Optional)_</sup>[#providing-operations]

While implementing this tool, we had to find solutions for a better integration of the GraphQL
ecosystem and ESLint core.

GraphQL's operations can be distributed across many files, while ESLint operates on one file at a
time. If you are using GraphQL fragments in separate files, some rules might yield incorrect
results, due the missing information.

To workaround that, we allow you to provide additional information on your GraphQL operations,
making it available for rules while doing the actual linting.

The GraphQL ESLint plugin integrates seamlessly with
[GraphQL Config](https://the-guild.dev/graphql/config), which it uses to automatically load your
sibling operations and fragments.

> [!TIP]
>
> GraphQL Config uses [`GraphQL Tools`](https://the-guild.dev/graphql/tools) and its loaders under
> the hood to handle the loading of operations and fragments. It also
> [supports multiple ways to specify them](https://the-guild.dev/graphql/config/docs/user/documents).

<GraphqlConfigInfo name="operations" configKey="documents" />

Example of providing GraphQL operations:

<Tabs items={['GraphQL Config', 'Programmatic Usage']}>
<Tabs.Tab>

```js filename="graphql.config.js"
export default {
  // a path to a local `.graphql` file
  documents: './users.graphql',

  // a glob expression to load multiple files
  documents: './src/**/*.graphql',

  // paths to multiple `.graphql` files
  documents: ['./src/users.graphql', './src/posts.graphql', './src/user-fields.graphql']
}
```

</Tabs.Tab>

<Tabs.Tab>

```diff filename="eslint.config.js"
import graphqlPlugin from '@graphql-eslint/eslint-plugin'

export default [
  // ... other config
  {
    files: ['**/*.graphql'],
    languageOptions: {
      parser: graphqlPlugin.parser,
      parserOptions: {
        graphQLConfig: {
          schema: './schema.graphql',
+         documents: './src/**/*.graphql'
        }
      }
    },
    plugins: {
      '@graphql-eslint': graphqlPlugin
    },
    rules: {
      '@graphql-eslint/unique-operation-name': 'error'
    }
  }
]
```

</Tabs.Tab>
</Tabs>
</Steps>

## Usage

<MDXRemote
  compiledSource={await createIndexPage(await getPageMap('/docs/usage'))}
  components={{
    Cards,
    GraphQLIcon,
    JSIcon,
    HalfIcon,
    StackIcon,
    GearIcon,
    SvelteIcon,
    VueIcon,
    AstroIcon,
    PrettierIcon
  }}
/>
